#pragma once

#include <memory>
class CByteCodeFile;
class CBytecodeWriter;
class CNamespaceDescription;
class CTypeDescription;
class CCompilerContext;

class CByteCodeGenerator
{
public:
    std::shared_ptr<CByteCodeFile> CreateByteCodeFile(std::shared_ptr<CCompilerContext> InCompilerContext);

protected:
    void AssignNamespaceMemberIndex(std::shared_ptr<CNamespaceDescription> InNamespace, std::shared_ptr<CCompilerContext> InCompilerContext);
    void AssignMemberFieldIndex(std::shared_ptr<CTypeDescription> InClass,std::shared_ptr<CCompilerContext> InCompilerContext);
    void AssignMemberFunctionIndex(std::shared_ptr<CTypeDescription> InClass,std::shared_ptr<CCompilerContext> InCompilerContext);

    void WriteNamespace(std::shared_ptr<CBytecodeWriter> InWriter
        , std::shared_ptr<CNamespaceDescription> InNamespace
        , std::shared_ptr<CCompilerContext> InCompilerContext
        ,bool bIsGlobalNamespace);

    void WriteClasses(std::shared_ptr<CBytecodeWriter> InWriter
        , std::shared_ptr<CCompilerContext> InCompilerContext);

    void WriteClass(std::shared_ptr<CBytecodeWriter> InWriter
        , std::shared_ptr<CTypeDescription> InClass
        , std::shared_ptr<CCompilerContext> InCompilerContext);

    void WriteClassesContent(std::shared_ptr<CBytecodeWriter> InWriter
        , std::shared_ptr<CCompilerContext> InCompilerContext);

    void WriteClassContent(std::shared_ptr<CBytecodeWriter> InWriter
        , std::shared_ptr<CTypeDescription> InClass
        , std::shared_ptr<CCompilerContext> InCompilerContext);
};